package com.example.demo.api;

import com.example.demo.exception.ApplicationException;
import com.example.demo.game.MatchRequest;
import com.example.demo.game.MatchResponse;
import com.example.demo.game.Matcher;
import com.example.demo.game.OnLineUserManager;
import com.example.demo.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.TextWebSocketHandler;


@Slf4j
@Component
public class MatchApI extends TextWebSocketHandler {

   @Autowired
    ObjectMapper objectMapper;
    @Autowired
    private OnLineUserManager onLineUserManager;

    @Autowired
    private Matcher matcher;
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {   //连接建立成功后
        //玩家上线
        log.info("连接建立成功");

        //获取到登录成功后的用户（通过session即可获取）
            User user = (User) session.getAttributes().get("userInfo");
           if(user==null||user.getUserId()<=0){
            MatchResponse matchResponse = new MatchResponse();
            matchResponse.setOk(false);
            matchResponse.setReason("用户未登录");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(matchResponse)));
            return;
        }

       //为了防止多发的问题（同一个用户在不同的浏览器登录），我们设置如果用户已经登陆，则不可以再次登录
log.info(onLineUserManager.getUserSession(user.getUserId())+" Session为 ");
           log.info(session+" 该用户的session为 ");
       if(onLineUserManager.getUserSession(user.getUserId())!=null
             ){        //这里代表用户登录了
           log.info("用户已经登录过了");
           MatchResponse matchResponse = new MatchResponse();
           matchResponse.setOk(true);
           matchResponse.setReason("多开现象");
           log.info("游戏大厅发生多开了");
           matchResponse.setMessage("repeatConnection");
           session.sendMessage(new TextMessage(objectMapper.writeValueAsString(matchResponse)));
           session.close();   //关闭websocket连接
           return;         //这里不return，这调用玩连接关闭的代码后，还会往下执行
       }
       //拿到登录的用户信息就可以设置为玩家上线状态了
        onLineUserManager.UserEnterGameHall(user.getUserId(),session);
        log.info("玩家："+user.getUsername()+"进入了游戏");
    }

    //这里主要就是处理请求的
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {

        log.info("进入这里代表你与第一个方法同时运行");
            User user = (User) session.getAttributes().get("userInfo");
        if(user==null||user.getUserId()<=0){
            MatchResponse matchResponse = new MatchResponse();
            matchResponse.setOk(false);
            matchResponse.setReason("用户未登录");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(matchResponse)));
            return;
        }
        String payload = message.getPayload();  //得到是Json格式的字符串，我们要把它变为MatchRequest的对象格式

       MatchRequest request = objectMapper.readValue(payload, MatchRequest.class);
       MatchResponse response = new MatchResponse();

       if(request.getMessage().equals("startMatch")){
           //把玩家加入匹配队列
           // TODO 先创建一个用户的匹配队列，把进去匹配队列的用户加进去
           matcher.add(user);
           //如果是startMatch就需要给前端发挥startMatch,说明正常开始匹配了；然后前端就需要根据返回来的信息进行把那个开始匹配改为：匹配中。。
           response.setOk(true);
           response.setMessage("startMatch");

       }else if(request.getMessage().equals("stopMatch")){

           //退出匹配队列
           // TODO 先创建一个用户的匹配队列，把当前用户从匹配队列移除出去
           matcher.remove(user);

           //如果是stopMatch就需要给前端返回stopMatch,说明正常开始匹配了；然后前端就需要根据返回来的信息进行把那个匹配中。。改为：开始匹配
           response.setOk(true);
           response.setMessage("stopMatch");

        }else{
          //异常情况
           response.setOk(false);
           response.setMessage("非法的匹配请求");

       }
        String json = objectMapper.writeValueAsString(response);
        session.sendMessage(new TextMessage(json));
    }


    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
                //发生连接异常后，我们就需要让玩家下线

        User user = (User) session.getAttributes().get("userInfo");

            if(user==null||user.getUserId()<=0){
             /*   MatchResponse matchResponse = new MatchResponse();
                matchResponse.setOk(false);
                matchResponse.setReason("用户未登录");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(matchResponse)));*/
                return;
            }

        WebSocketSession socketSession = onLineUserManager.getUserSession(user.getUserId());
        if(socketSession==session){
            onLineUserManager.UserRemoveGameHall(user.getUserId());    //获取到玩家信息后，设置为下线状态
        }
        matcher.remove(user);

    }


    //TODO 明天的问题，为啥同一个用户登录的时候，就是socketSession和session不同；不同的用户socketSession和session就相同
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        //连接关闭后，我们就需要让玩家下线
       log.info("连接进入关闭");
        User user = (User) session.getAttributes().get("userInfo");
        if(user==null||user.getUserId()<=0){   //如果设置登录拦截器就不会出现这里的问题了
            //用户未登录

         /*   MatchResponse matchResponse = new MatchResponse();
            matchResponse.setOk(false);
            matchResponse.setReason("用户未登录");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(matchResponse)));*/
            return;
        }
        WebSocketSession socketSession = onLineUserManager.getUserSession(user.getUserId());   //socketSession是我们存的session

        if(socketSession!=session){
            System.out.println("socketSession不等于session");
        }
        if(socketSession==session){
            log.info("socketSession等于session");
         onLineUserManager.UserRemoveGameHall(user.getUserId());      //获取到玩家信息后，设置为下线状态

        }
     matcher.remove(user);

    }
}
